//! Logging utilities using tracing
//!
//! This module re-exports tracing and provides utilities for initializing logging.

/// Re-export tracing so that projects using ribo don't need to depend on tracing directly
pub use tracing;

use tracing_subscriber::{fmt, EnvFilter};

pub use tracing::{debug, error, info, warn};

#[derive(Debug, Clone, Copy)]
pub enum LogLevel {
    ERROR,
    WARN,
    INFO,
    DEBUG,
    TRACE,
}

impl From<LogLevel> for tracing::Level {
    fn from(level: LogLevel) -> Self {
        match level {
            LogLevel::ERROR => tracing::Level::ERROR,
            LogLevel::WARN => tracing::Level::WARN,
            LogLevel::INFO => tracing::Level::INFO,
            LogLevel::DEBUG => tracing::Level::DEBUG,
            LogLevel::TRACE => tracing::Level::TRACE,
        }
    }
}

/// Initialize the global tracing subscriber with a default configuration
///
/// This sets up a subscriber with:
/// - Environment filter using `RUST_LOG` environment variable
/// - Target information included in logs
/// - File and line number information
/// - RFC3339 formatted timestamps
/// - Colored output enabled

pub fn init_log(level: LogLevel) {
    let filter = EnvFilter::builder()
        .with_default_directive(tracing::Level::from(level).into())
        .from_env_lossy(); // allow RUST_LOG to override

    use time::format_description::parse;
    use time::UtcOffset;

    let format = parse("[year]-[month padding:zero]-[day padding:zero] [hour]:[minute]:[second]")
        .expect("Failed to parse time format");

    // Obtain the local time offset
    let offset = UtcOffset::current_local_offset().unwrap_or(UtcOffset::UTC);

    // Create a custom timer using the offset and format
    let timer = fmt::time::OffsetTime::new(offset, format);
    tracing_subscriber::fmt()
        .with_env_filter(filter)
        .with_timer(timer) // simplified timestamp
        .with_target(false)
        .with_file(true)
        .with_line_number(true)
        .with_ansi(true)
        // .with_writer(std::io::stdout)
        // .compact()
        .init();
}

/// Initialize the global tracing subscriber with custom configuration
///
/// # Arguments
///
/// * `env_filter` - A custom environment filter string (e.g., "info", "debug", "my_crate=trace")
/// * `include_ansi` - Whether to include ANSI color codes in output
pub fn init_with_filter(env_filter: &str, include_ansi: bool) {
    fmt()
        .with_env_filter(EnvFilter::new(env_filter))
        .with_target(true)
        .with_file(true)
        .with_line_number(true)
        .with_timer(fmt::time::LocalTime::rfc_3339())
        .with_ansi(include_ansi)
        .init()
}

/// Initialize the global tracing subscriber with a custom formatter
///
/// This allows for more fine-grained control over the logging setup
pub fn init_with_config<F>(config_fn: F)
where
    F: Fn(fmt::SubscriberBuilder) -> fmt::SubscriberBuilder,
{
    let subscriber = fmt::Subscriber::builder();
    let configured_subscriber = config_fn(subscriber);
    configured_subscriber.init()
}
